import json
import os
import threading
from typing import Dict, List, Optional, Any
from datetime import datetime
import uuid
import logging

logger = logging.getLogger(__name__)

class JSONStorage:
    """JSON文件存储管理器"""
    
    def __init__(self, data_dir: str = "data"):
        self.data_dir = data_dir
        self.lock = threading.RLock()  # 线程安全锁
        self._ensure_data_dir()
        
        # 数据文件路径
        self.users_file = os.path.join(data_dir, "users.json")
        self.tasks_file = os.path.join(data_dir, "tasks.json")
        self.sessions_file = os.path.join(data_dir, "sessions.json")
        self.logs_file = os.path.join(data_dir, "logs.json")
        
        # 初始化数据文件
        self._init_data_files()
    
    def _ensure_data_dir(self):
        """确保数据目录存在"""
        if not os.path.exists(self.data_dir):
            os.makedirs(self.data_dir)
            logger.info(f"Created data directory: {self.data_dir}")
    
    def _init_data_files(self):
        """初始化数据文件"""
        files = [
            (self.users_file, []),
            (self.tasks_file, []),
            (self.sessions_file, {}),
            (self.logs_file, [])
        ]
        
        for file_path, default_data in files:
            if not os.path.exists(file_path):
                self._write_json(file_path, default_data)
                logger.info(f"Initialized data file: {file_path}")
    
    def _read_json(self, file_path: str) -> Any:
        """读取JSON文件"""
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                return json.load(f)
        except (FileNotFoundError, json.JSONDecodeError) as e:
            logger.error(f"Error reading {file_path}: {e}")
            return [] if file_path != self.sessions_file else {}
    
    def _write_json(self, file_path: str, data: Any):
        """写入JSON文件"""
        try:
            with open(file_path, 'w', encoding='utf-8') as f:
                json.dump(data, f, ensure_ascii=False, indent=2, default=str)
        except Exception as e:
            logger.error(f"Error writing {file_path}: {e}")
            raise
    
    # 用户相关操作
    def get_users(self) -> List[Dict]:
        """获取所有用户"""
        with self.lock:
            return self._read_json(self.users_file)
    
    def get_user_by_id(self, user_id: str) -> Optional[Dict]:
        """根据ID获取用户"""
        users = self.get_users()
        for user in users:
            if user.get('id') == user_id:
                return user
        return None
    
    def get_user_by_username(self, username: str) -> Optional[Dict]:
        """根据用户名获取用户"""
        users = self.get_users()
        for user in users:
            if user.get('username') == username:
                return user
        return None
    
    def create_user(self, user_data: Dict) -> Dict:
        """创建用户"""
        with self.lock:
            users = self.get_users()
            
            # 检查用户名和邮箱是否已存在
            for user in users:
                if user.get('username') == user_data.get('username'):
                    raise ValueError("用户名已存在")
                if user.get('email') == user_data.get('email'):
                    raise ValueError("邮箱已存在")
            
            # 创建新用户
            new_user = {
                'id': str(uuid.uuid4()),
                'username': user_data['username'],
                'email': user_data['email'],
                'full_name': user_data.get('full_name', ''),
                'hashed_password': user_data['hashed_password'],
                'role': user_data.get('role', 'user'),
                'is_active': user_data.get('is_active', True),
                'created_at': datetime.utcnow().isoformat(),
                'last_login': None
            }
            
            users.append(new_user)
            self._write_json(self.users_file, users)
            logger.info(f"User created: {new_user['username']}")
            return new_user
    
    def update_user(self, user_id: str, update_data: Dict) -> Optional[Dict]:
        """更新用户"""
        with self.lock:
            users = self.get_users()
            
            for i, user in enumerate(users):
                if user.get('id') == user_id:
                    users[i].update(update_data)
                    self._write_json(self.users_file, users)
                    logger.info(f"User updated: {user_id}")
                    return users[i]
            
            return None
    
    # 任务相关操作
    def get_tasks(self) -> List[Dict]:
        """获取所有任务"""
        with self.lock:
            return self._read_json(self.tasks_file)
    
    def get_task_by_id(self, task_id: str) -> Optional[Dict]:
        """根据ID获取任务"""
        tasks = self.get_tasks()
        for task in tasks:
            if task.get('id') == task_id:
                return task
        return None
    
    def create_task(self, task_data: Dict) -> Dict:
        """创建任务"""
        with self.lock:
            tasks = self.get_tasks()
            
            new_task = {
                'id': str(uuid.uuid4()),
                'name': task_data['name'],
                'description': task_data.get('description', ''),
                'urls': task_data['urls'],
                'status': 'pending',
                'progress': 0.0,
                'pages_crawled': 0,
                'pages_total': 0,
                'success_rate': 0.0,
                'errors_count': 0,
                'results': [],
                'logs': [],
                'config': task_data.get('config', {}),
                'created_at': datetime.utcnow().isoformat(),
                'updated_at': datetime.utcnow().isoformat(),
                'started_at': None,
                'completed_at': None
            }
            
            tasks.append(new_task)
            self._write_json(self.tasks_file, tasks)
            logger.info(f"Task created: {new_task['id']}")
            return new_task
    
    def update_task(self, task_id: str, update_data: Dict) -> Optional[Dict]:
        """更新任务"""
        with self.lock:
            tasks = self.get_tasks()
            
            for i, task in enumerate(tasks):
                if task.get('id') == task_id:
                    tasks[i].update(update_data)
                    tasks[i]['updated_at'] = datetime.utcnow().isoformat()
                    self._write_json(self.tasks_file, tasks)
                    logger.info(f"Task updated: {task_id}")
                    return tasks[i]
            
            return None
    
    def delete_task(self, task_id: str) -> bool:
        """删除任务"""
        with self.lock:
            tasks = self.get_tasks()
            
            for i, task in enumerate(tasks):
                if task.get('id') == task_id:
                    del tasks[i]
                    self._write_json(self.tasks_file, tasks)
                    logger.info(f"Task deleted: {task_id}")
                    return True
            
            return False
    
    # 会话相关操作（模拟Redis）
    def set_session(self, key: str, value: Any, expire_seconds: Optional[int] = None):
        """设置会话数据"""
        with self.lock:
            sessions = self._read_json(self.sessions_file)
            
            session_data = {
                'value': value,
                'created_at': datetime.utcnow().isoformat(),
                'expire_at': None
            }
            
            if expire_seconds:
                expire_at = datetime.utcnow().timestamp() + expire_seconds
                session_data['expire_at'] = expire_at
            
            sessions[key] = session_data
            self._write_json(self.sessions_file, sessions)
    
    def get_session(self, key: str) -> Optional[Any]:
        """获取会话数据"""
        with self.lock:
            sessions = self._read_json(self.sessions_file)
            
            if key not in sessions:
                return None
            
            session_data = sessions[key]
            
            # 检查是否过期
            if session_data.get('expire_at'):
                if datetime.utcnow().timestamp() > session_data['expire_at']:
                    del sessions[key]
                    self._write_json(self.sessions_file, sessions)
                    return None
            
            return session_data['value']
    
    def delete_session(self, key: str) -> bool:
        """删除会话数据"""
        with self.lock:
            sessions = self._read_json(self.sessions_file)
            
            if key in sessions:
                del sessions[key]
                self._write_json(self.sessions_file, sessions)
                return True
            
            return False
    
    # 日志相关操作
    def add_log(self, log_data: Dict):
        """添加日志"""
        with self.lock:
            logs = self._read_json(self.logs_file)
            
            log_entry = {
                'id': str(uuid.uuid4()),
                'timestamp': datetime.utcnow().isoformat(),
                'level': log_data.get('level', 'INFO'),
                'message': log_data['message'],
                'task_id': log_data.get('task_id'),
                'user_id': log_data.get('user_id'),
                'extra': log_data.get('extra', {})
            }
            
            logs.append(log_entry)
            
            # 保持日志数量在合理范围内（最多1000条）
            if len(logs) > 1000:
                logs = logs[-1000:]
            
            self._write_json(self.logs_file, logs)
    
    def get_logs(self, task_id: Optional[str] = None, limit: int = 100) -> List[Dict]:
        """获取日志"""
        logs = self._read_json(self.logs_file)
        
        if task_id:
            logs = [log for log in logs if log.get('task_id') == task_id]
        
        # 按时间倒序排列，返回最新的日志
        logs.sort(key=lambda x: x['timestamp'], reverse=True)
        return logs[:limit]


# 全局存储实例
storage = JSONStorage()
